package cn.starrysky.hrm.controller;

import cn.starrysky.hrm.docment.CourseDoc;
import cn.starrysky.hrm.query.CourseDocQuery;
import cn.starrysky.hrm.repository.CourseElasticsearchRepository;
import cn.starrysky.hrm.resultmapping.HighlightResultMapper;
import cn.starrysky.hrm.util.AjaxResult;
import cn.starrysky.hrm.util.PageList;
import cn.starrysky.hrm.vo.AggVo;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.swing.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/courseSearch")
public class CourseSearchController {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private CourseElasticsearchRepository courseElasticsearchRepository;
    @Autowired
    private HighlightResultMapper highlightResultMapper;

    @PostMapping("/addOrUpdate")
    @PreAuthorize("hasAuthority('courseSearch:addOrUpdate')")
    public AjaxResult addOrUpdate(@RequestBody CourseDoc courseDoc){
        //System.out.println(courseDoc);
        courseElasticsearchRepository.save(courseDoc);
        return AjaxResult.me();
    }
    @DeleteMapping("/delete/{id}")
    public AjaxResult delete(@PathVariable("id") Long id){
        courseElasticsearchRepository.deleteById(id);
        return AjaxResult.me();
    }
    @PostMapping("/queryCourses")
    public PageList<CourseDoc> queryCourses(@RequestBody CourseDocQuery docQuery){
       // System.out.println(docQuery);
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        //条件  组合查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //聚合查询
        builder.addAggregation(AggregationBuilders.terms("tenantNameAgg").field("tenantName").order(Terms.Order.count(false)).size(20));
        //builder.addAggregation(AggregationBuilders.terms("couseTypeAgg").field("courseTypeName").order(Terms.Order.count(false)).size(20));
        //模糊查询的关键字
        String keyword = docQuery.getKeyword();
        if(StringUtils.isNotBlank(keyword)){
            //名字
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", keyword));
            //boolQueryBuilder.should(QueryBuilders.matchQuery("forUser", keyword));
        }
        //过滤
        String priceMin = docQuery.getPriceMin();
        if(null!=priceMin){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(priceMin));
        }
        String priceMax = docQuery.getPriceMax();
        if(null!=priceMax){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(priceMax));
        }
        builder.withQuery(boolQueryBuilder);

        //高亮查询
        //设置高亮显示
        HighlightBuilder.Field field = new HighlightBuilder.Field("name")
                .preTags("<font style='color:red'><b>").postTags("</b></font>");
        builder.withHighlightFields(field);  // 名字高亮

        //排序
        String sortField = docQuery.getSortField();
        System.out.println("排序字段===="+sortField);
        //排序的字段========================= 默认价格
        String sortFiledName = "price";
        if (StringUtils.isNotBlank(sortField)) {

            switch (sortField.toLowerCase()) {
                case "xl":
                    sortFiledName = "saleCount"; //销量
                    break;
                case "xp":
                    sortFiledName = "onlineTime"; //新平
                    break;
                case "pl":
                    sortFiledName = "commentCount"; //评论
                    break;
                case "rq":
                    sortFiledName = "viewCount"; //人气 浏览量
                    break;
            }
            //排序的类型
            String sortType = docQuery.getSortType();
            System.out.println("排序方式==========="+sortType);
            //默认 升序
            SortOrder sortOrder = SortOrder.ASC;
            //ruguo如果排序不为空 且为desc 倒序  不然就是升序
            sortOrder=StringUtils.isNotBlank(sortType)&&sortType.toLowerCase()
                    .equals("desc") ? SortOrder.DESC : sortOrder;
            builder.withSort(new FieldSortBuilder(sortFiledName).order(sortOrder));
        }
        //Sort.by();
        //分页
        builder.withPageable(PageRequest.of(docQuery.getPage()-1, docQuery.getRows()));

        //查询
        //Page<CourseDoc> page = courseElasticsearchRepository.search(builder.build());
        //高亮结果映射
        AggregatedPage<CourseDoc> page = elasticsearchTemplate.queryForPage(builder.build(), CourseDoc.class, highlightResultMapper);

        //封装聚合的数据
        Map<String, List<AggVo>> map = new HashMap<>();
        //根据名字获取聚合查询的结果
        StringTerms tenantNameAgg = (StringTerms) page.getAggregation("tenantNameAgg");
        //创建list集合 封装tenant聚合的结果
        List<AggVo> tVoList = new ArrayList<>();
        List<StringTerms.Bucket> tenantBuckets = tenantNameAgg.getBuckets();
        tenantBuckets.stream().forEach(tbucket -> {
            AggVo vo = new AggVo(tbucket.getKeyAsString(), tbucket.getDocCount());
            tVoList.add(vo);
        });
        map.put("tenantNameAgg", tVoList);
//
//        //根据名字获取聚合查询的结果
//        StringTerms courseTypeNameAgg = (StringTerms) page.getAggregation("couseTypeAgg");
//        //创建list集合 封装tenant聚合的结果
//        List<AggVo> cVoList = new ArrayList<>();
//        List<StringTerms.Bucket> courseTypeBuckets = courseTypeNameAgg.getBuckets();
//        courseTypeBuckets.stream().forEach(cbucket -> {
//            AggVo vo = new AggVo(cbucket.getKeyAsString(), cbucket.getDocCount());
//            cVoList.add(vo);
//        });
//        map.put("couseTypeAgg",cVoList);

        return new PageList<CourseDoc>(page.getTotalElements(),page.getContent(),map);
    }

}
